package com.weipai.education.service.impl;

import com.alibaba.fastjson.JSON;
import com.weipai.education.dao.MenuDao;
import com.weipai.education.dao.RoleDao;
import com.weipai.education.dao.UserDao;
import com.weipai.education.enums.RetCode;
import com.weipai.education.model.Menu;
import com.weipai.education.model.Role;
import com.weipai.education.model.RoleMenu;
import com.weipai.education.model.User;
import com.weipai.education.model.api.PageResult;
import com.weipai.education.model.api.Response;
import com.weipai.education.model.api.SaveRoleMenusRequest;
import com.weipai.education.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @Author: 曹朋飞
 * @Date: 2018/12/11 15:24
 */
@Service
public class RoleServiceImpl implements RoleService {
    
    @Autowired
    private RoleDao roleDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private MenuDao menuDao;
    
    @Override
    public Response list(String status) {
        Response response = new Response();
        List<Map<String, Object>> list = roleDao.list(status);
        if (list.size() > 0) {
            PageResult<Map<String, Object>> pageList = new PageResult<>(list, 1, 20, list.size());
            response.put("pageList", pageList);
            response.setCode(RetCode.SUCCESS);
        } else {
            response.setCode(RetCode.NOT_DATA);
        }
        return response;
    }

    @Override
    public Response save(Role role) {
        Response response = new Response();
        if(null !=role.getId()){
            roleDao.update(role);
        }else{
            role.setRoleStatus(0);
            roleDao.insert(role);
        }
        response.setCode(RetCode.SUCCESS);
        return response;
    }

    @Override
    public Response deleteById(String id) {
        Response response = new Response();
        List<User> user = userDao.getUserByRoleId(id);
        if(user.isEmpty()){
            response.setCode(RetCode.RELEVANCE_DATA);
        }else{
            roleDao.deleteById(id);
            response.setCode(RetCode.SUCCESS);
        }
        return response;
    }

    @Override
    public Response changeStatus(String id) {
        Response response = new Response();
        Role role = roleDao.selectByPrimaryKey(id);
        if(null!=role){
            if(0 == role.getRoleStatus()){
                List<User> user = userDao.getUserByRoleId(id);
                if(!user.isEmpty()){
                    response.setCode(RetCode.RELEVANCE_DATA);
                    return response;
                }else{
                    role.setRoleStatus(-1);
                }
            }else{
                role.setRoleStatus(0);
            }
            roleDao.update(role);
            response.setCode(RetCode.SUCCESS);
            return response;
        }else{
            response.setCode(RetCode.NOT_DATA);
        }
        return response;
    }

    @Override
    public Response getMenusByRoleId(String roleId) {
        Response response = new Response();
        //获得所有  菜单 权限
        List<Menu> allMenus = menuDao.getAllMenus();
        //获得 角色 所拥有 权限
        List<Menu> roleMenus = menuDao.getMenusByRoleId(roleId);

        if (roleMenus == null) {
            roleMenus = new ArrayList<>(); //新增角色是返回空的权限列表
        }

        List<Map<String, Object>> viewMenus = new ArrayList<>();
        //把 角色 的一级菜单 id  和对象 放到map
        Map<Integer, Menu> menuIdMap = getMenuIdMap(roleMenus);

        for (Menu menu : allMenus) {
            Map<String, Object> menuMap = new LinkedHashMap<>();
            //先把第一层 菜单拿出来
            if (menu.getParentId() == null) {
                //通过 一级 id  获得其对象
                Menu validMenu = menuIdMap.get(menu.getId());
                menuMap.put("menuId", menu.getId());
                menuMap.put("name", menu.getName());
                menuMap.put("icon", menu.getIcon());
                menuMap.put("type", menu.getType());
                menuMap.put("url", menu.getUrl());
                //判断此 一级菜单是否可用
                menuMap.put("valid", validMenu == null ? 0 : 1);
                if (menu.getType() == 1) {  //假如可用,
                    menuMap.put("perms", getValidPerms(menu, validMenu));    //判断 其子权限是否可用
                } else if (menu.getType() == 0) {
                    //menuMap.put("subMenus", getSubMenus(allMenus, menuIdMap, menu));
                    menuMap.put("children", getSubMenus(allMenus, menuIdMap, menu));
                }
                viewMenus.add(menuMap);
            }
        }

        response.setCode(RetCode.SUCCESS);
        response.put("menus", viewMenus);
        return response;
    }

    @Override
    public Response saveRoleMenus(String data) {
        SaveRoleMenusRequest request = JSON.parseObject(data, SaveRoleMenusRequest.class);
        Response response = new Response();
        List<Map<String, Object>> menus = request.getMenus();
        menuDao.deleteRoleMenus(request.getRoleId());
        menuDao.saveRoleMenus(toRoleMenus(request.getRoleId(), menus));
        response.setCode(RetCode.SUCCESS);
        return response;
    }

    @Override
    public Response saveRole(String roleName, String roleDesc, Integer id) {
        Response response = new Response();
        if(null!=id){
            Role role = roleDao.selectByPrimaryKey(Integer.toString(id));
            role.setRoleName(roleName).setRoleDesc(roleDesc);
            roleDao.update(role);
        }else{
            Role role = new Role();
            role.setRoleName(roleName).setRoleDesc(roleDesc).setRoleStatus(0);
            roleDao.insert(role);
        }
        response.setCode(RetCode.SUCCESS);
        return response;
    }

    @Override
    public Integer verifyRoleIdAndMenuId(Integer roleId, Integer menuId) {
        return menuDao.verifyRoleIdAndMenuId(roleId, menuId);
    }

    public List<RoleMenu> toRoleMenus(Integer roleId, List<Map<String, Object>> menus) {
        List<RoleMenu> roleMenus = new ArrayList<>();
        for (Map<String, Object> menu : menus) {
            RoleMenu roleMenu = new RoleMenu();
            roleMenu.setRoleId(roleId);
            roleMenu.setMenuId(Integer.valueOf(menu.get("menuId") + ""));
            roleMenu.setPerms(menu.get("perms") == null ? "" : menu.get("perms") + "");
            roleMenus.add(roleMenu);
        }
        return roleMenus;
    }

    private List<Map<String, Object>> getSubMenus(List<Menu> menus, Map<Integer, Menu> menuIdMap, Menu parentMenu) {
        List<Map<String, Object>> subMenus = new ArrayList<>();
        for (Menu menu : menus) {
            if (parentMenu.getId().equals(menu.getParentId())) {
                Map<String, Object> menuMap = getValidMenuMap(menu, menuIdMap);
                subMenus.add(menuMap);
                if (menu.getType() == 0) {
                    menuMap.put("subMenus", getSubMenus(menus, menuIdMap, menu));
                }
            }
        }
        return subMenus;
    }

    private Map<Integer, Menu> getMenuIdMap(List<Menu> menus) {
        Map<Integer, Menu> map = new HashMap<>();
        for (Menu menu : menus) {
            map.put(menu.getId(), menu);
        }
        return map;
    }

    //判断 一级菜单 权限是否可用
    private Map<String, Object> getValidMenuMap(Menu menu, Map<Integer, Menu> menuIdMap) {
        Map<String, Object> menuMap = new LinkedHashMap<>();
        menuMap.put("menuId", menu.getId());
        menuMap.put("name", menu.getName());
        menuMap.put("icon", menu.getIcon());
        menuMap.put("type", menu.getType());
        menuMap.put("url", menu.getUrl());
        menuMap.put("valid", 0);

        Menu validMenu = menuIdMap.get(menu.getId());

        menuMap.put("valid", validMenu == null ? 0 : 1);

        if (menu.getType() == 1) {
            //menuMap.put("perms", getValidPerms(menu, validMenu));
            menuMap.put("children", getValidPerms(menu, validMenu));
        }
        return menuMap;
    }

    //判断 其子权限是否可用
    private List<Map<String, Object>> getValidPerms(Menu menu, Menu validMenu) {
        List<Map<String, Object>> permList = new ArrayList<>();
        //得到 参数对应值
        Map<String, String> operation = menuDao.getOperation();

        if (!StringUtils.isEmpty(menu.getPerms())) {
            //放到数组里
            String[] perms = menu.getPerms().split(",");
            for (String perm : perms) {
                Map<String, Object> perm2 = new LinkedHashMap<>();
                perm2.put("permCode", perm);
                //perm2.put("permName", operation.get(perm));
                perm2.put("name", operation.get(perm));
                if (validMenu != null && validMenu.getPerms().indexOf(perm) != -1) {
                    perm2.put("valid", 1);
                } else {
                    perm2.put("valid", 0);
                }
                permList.add(perm2);
            }
        }
        return permList;
    }
}
